from location import TripLoader
from scipy.ndimage import imread
from scipy.misc import imsave, toimage
from topo_build import *
import os
import sys
import kde
import numpy as np
import skeleton
import graph_extract
import refine_topology
import graphdb_matcher_run
import process_map_matches
import topo_build
import streetmap


def match_trip(graphdb_filename, trips_path, output_directory):
    constraint_length = 300; max_dist = 350
    match_graphdb = graphdb_matcher_run.MatchGraphDB(graphdb_filename, constraint_length, max_dist)
    all_trip_files = filter(lambda x: x.startswith("trip_") and x.endswith(".txt"), os.listdir(trips_path))
    
    for i in range(0, len(all_trip_files)):
        sys.stdout.write("\rProcessing trip " + str(i + 1) + "/" + str(len(all_trip_files)) + "... ")
        sys.stdout.flush()
        match_graphdb.process_trip(trips_path, all_trip_files[i], output_directory)

def prune_match(graphdb_filename, matched_trips_directory, output_filename):
    p = process_map_matches.ProcessMapMatches()
    p.process(graphdb_filename, matched_trips_directory, output_filename, output_filename.replace(".db", "_traces.txt"))

def clean_and_mkdir(folder_name):
    if not os.path.exists(folder_name):
        os.mkdir(folder_name)
    else:
        for i in os.listdir(folder_name):
            path_file = os.path.join(folder_name, i)
            if os.path.isfile(path_file):
                os.remove(path_file)

def run():

    trips_path = "trips/trips_1m/"
    input_filename = "kde.png"
    skeleton_filename = "skeleton.png"
    bounding_box_filename = "bounding_boxes/bounding_box_1m.txt"
    graphdb_filename = "skeleton_maps/skeleton_map_1m.db"

    matched_trips_directory_1 = "trips/matched_trips_1m/"
    graphdb_filename_matched_1 = "skeleton_maps/skeleton_map_1m_mm1.db"
    matched_traces_filename = "skeleton_maps/skeleton_map_1m_mm1_traces.txt"

    graphdb_filename_pruned = "skeleton_maps/skeleton_map_1m_mm1_tr.db"
    matched_trips_directory_2 = "trips/matched_trips_1m_mm1_tr/"
    graphdb_filename_matched_2 = "skeleton_maps/skeleton_map_1m_mm2.db"
    track_filename = "skeleton_maps/skeleton_map_1m_mm2_traces.txt"

    clean_and_mkdir("skeleton_maps")
    clean_and_mkdir("skeleton_images")
    clean_and_mkdir("bounding_boxes")
    clean_and_mkdir(matched_trips_directory_1)
    clean_and_mkdir(matched_trips_directory_2)

    k = kde.KDE()
    trips = TripLoader.load_all_trips(trips_path)
    k.create_kde_with_trips(trips)

    input_kde = imread(input_filename)
    s = skeleton.GrayscaleSkeleton()
    skeleton_s = s.skeletonize(input_kde)
    toimage(skeleton_s, cmin=0, cmax=255).save(skeleton_filename)

    bounding_box_file = open(bounding_box_filename, 'r')
    bounding_box_values = bounding_box_file.readline().strip("\n").split(" ")
    bounding_box_file.close()
    
    skeleton_g = imread(skeleton_filename)
    graph_extract.min_lat, graph_extract.min_lon, graph_extract.max_lat, graph_extract.max_lon = float(bounding_box_values[0]), float(bounding_box_values[1]), float(bounding_box_values[2]), float(bounding_box_values[3])
    graph_extract.height = len(skeleton_g)
    graph_extract.width = len(skeleton_g[0])
    graph_extract.yscale = graph_extract.height / (graph_extract.max_lat - graph_extract.min_lat)
    graph_extract.xscale = graph_extract.width / (graph_extract.max_lon - graph_extract.min_lon)
    
    g = graph_extract.Graph()
    g.extract(skeleton_g.astype(np.bool).astype(np.int), skeleton_g, graphdb_filename)

    match_trip(graphdb_filename, trips_path, matched_trips_directory_1)
    prune_match(graphdb_filename, matched_trips_directory_1, graphdb_filename_matched_1)

    r = refine_topology.RefineTopology(graphdb_filename_matched_1)
    r.process(matched_traces_filename, graphdb_filename_pruned)

    match_trip(graphdb_filename_pruned, trips_path, matched_trips_directory_2)
    prune_match(graphdb_filename_pruned, matched_trips_directory_2, graphdb_filename_matched_2)

    track_maps = read_track_file(track_filename)

    m = streetmap.StreetMap()
    m.load_graphdb(graphdb_filename_matched_2)
    topo = TopoBuild(m)
    topo.generate_lane(track_maps, "result.tab")
    print ("done")

if __name__ == "__main__":
   run()
